package com.runa.monitor.platinterface.platService;

import com.runa.monitor.comm.dto.Meter;
import com.runa.monitor.comm.dto.Node;
import com.runa.monitor.comm.entity.CommNetEquipment;
import com.runa.monitor.comm.entity.CommNetService;
import com.runa.monitor.platinterface.backwork.impl.NetStatusCallbackImpl;
import com.runa.monitor.platinterface.base.BaseContainer;
import com.runa.monitor.platinterface.mqtt.MqttUtil;
import com.runa.monitor.platinterface.netservice.client.ConcentratorClient;
import com.runa.monitor.platinterface.netservice.equipment.LangKaBoDriver;
import com.runa.monitor.platinterface.netservice.equipment.RunaNativeDriver;
import com.runa.monitor.platinterface.netservice.server.ConcentratorServer;
import com.runa.monitor.platinterface.netservice.server.ListenerServer;
import com.runa.monitor.platinterface.netservice.server.Server;
import com.runa.persistence.repository.CommNetEquipmentRepository;
import com.runa.persistence.repository.CommNetServiceRepository;
import com.runa.protocol.enums.ModbusType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * @author zhuj
 */
@Slf4j
@Order(999)
@Service
public class MeterService implements CommandLineRunner {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private CommNetServiceRepository commNetServiceRepository;
    @Resource
    private CommNetEquipmentRepository commNetEquipmentRepository;

    @Resource(name = "asyncResponseScheduler")
    private Executor executor;

    @Override
    public void run(String... args) {
        try {
            createRccServer();
            log.info("计量通信协议初始化完成---------");
        } catch (Exception e) {
            log.error("计量通信协议初始化错误——", e);
        }
    }


    private void asyncInitState(List<CommNetEquipment> commNetEquipmentList) {
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            MqttUtil.sendOnLineStateOfNoneContent(commNetEquipment.getId(), commNetEquipment.getSerial(), false);
        }
    }

    private void createRccServer() {
        //设置计量共用的异步线程池
        BaseContainer.setNetEquExecutor(executor);
        //创建网络状态变更回调
        BaseContainer.setNetStatusCallback(new NetStatusCallbackImpl(executor, repositoryService));
//        Set<RccService> services = rccRepository.getAllService();
        List<CommNetService> commNetServiceList = commNetServiceRepository.findAll();
        for (CommNetService commNetService : commNetServiceList) {
            if (commNetService.getEnable() == null || commNetService.getEnable() == 0) continue;
            Example<CommNetEquipment> merchantInfoExample = Example.of(CommNetEquipment.builder().service(commNetService.getId()).build());
            List<CommNetEquipment> commNetEquipmentList = commNetEquipmentRepository.findAll(merchantInfoExample);
            asyncInitState(commNetEquipmentList);
            protocolServer(commNetService);
        }
    }

    public void startServer(CommNetService service) {
        protocolServer(service);
    }

    public void stopServer(CommNetService service) {
        Server server = protocolServer(service);
        if (server != null) {
            server.shutdown();
        }
    }


    private Server protocolServer(CommNetService service) {
        try {
            switch (service.getProtocol()) {
                //瑞纳智能集中器专用协议端口服务
                case "RUNA_FMU":
                case "OTHER_RUNA_FMU":
                case "HWS_DEVICE":
                case "RUNA_LORA":
                case "RUNA_NATIVE":
                case "En_Meter":
                case "DFS_CLR"://潍坊丹弗斯的采集器
                case "HZ_FMU":
                case "FK_NBIot":
                case "JJN_FMU":
                case "DAOHENG_FMU":
                case "TIANGANG_FMU":
                case "HUANXIANG_FMU":
                case "LJE_FMU":
                case "LKB_FMU":
                case "LC_FMU":
                case "ELM_FMU":
                case "DB_FMU":
                case "DB_2_FMU":
                case "HZ_HZ-1_FMU":
                case "AP_FMU":
                case "THTF_FMU":
                case "QY_FMU":
                case "GD_FMU":
                case "JP_HD_DTU":
                case "LKB_DTU":
                    return ConcentratorServer.startServer(service.getPort(), service.getProtocol(), true);
                case "TIANGANG_UDP_FMU":
                case "HZ_TMP_FMU":
                case "JN_TMP":
                case "HDRX_FMU":
                case "SH_TMP":
                    return ConcentratorServer.startServer(service.getPort(), service.getProtocol(), false);
                case "SWP_DEVICE":
                case "PUBLIC_BUILD":
                    return ListenerServer.getInstance("50", ModbusType.MODBUS_RTU, service.getPort());
                case "USR_G780":
                    return ListenerServer.getInstance("88", ModbusType.MODBUS_RTU, service.getPort());
                case "FRS_CLIENT":
                    return ConcentratorClient.getInstance(service);
            }
        } catch (Exception e) {
            log.error("启动错误service:"+service.toString(), e);
        }
        return null;
    }

    public static void main(String[] args) {
////        NovoconDriver ncDriver = newComm NovoconDriver("00070003", 1000,
////                ListenerServer.getInstance("88", ModbusType.MODBUS_RTU, 4396));
////        NodeEquModel model = newComm NodeEquModel();
////        model.setIndex(1);
////        model.setSerial("1");
////        model.setPort(2);
////        model.setType(NodeEquModel.NodeEquType.LZ_VALVE);
////        ncDriver.init(Arrays.asList(model));
////        NetEqu.setInstance("00070003", ncDriver);
////        newComm ConcentratorServer("199.28.0.218", 4396, "HWS_DEVICE", "HWS_188");
////        HiwitsDriver hiwitsDriver = newComm HiwitsDriver("10710000127", 5000);
////        NodeEquModel model = newComm NodeEquModel();
////        model.setIndex(1);
////        model.setSerial("20100089");
////        model.setPort(2);
////        model.setType(NodeEquModel.NodeEquType.LZ_VALVE);
////        hiwitsDriver.init(Arrays.asList(model));
////        NetEqu.setInstance("10710000127", hiwitsDriver);
////
////        BufferedReader br = newComm BufferedReader(newComm InputStreamReader(System.in));
////        while (true) {
////            try {
////                br.readLine();
////                hiwitsDriver.readNodeEqu(Arrays.asList("20100089"), newComm RccTaskFunction.RnTask(1, "10710000127"), EquData.EquDataType.PUBLIC_UNIT);
////            } catch (IOException e) {
////
////            }
////        }
////        ConcentratorServer.startServer("199.28.0.218", 4396, "JJN_FMU", "JJN_METER");
////        Jjn8124Driver driver = newComm Jjn8124Driver("9311534174", 5000);
//        List<NodeEquModel> list = new ArrayList<>();
//        NodeEquModel model = new NodeEquModel();
//        model.setIndex(1);
//        model.setSerial("20100086");
//        model.setPort(2);
//        model.setType(NodeEquModel.NodeEquType.LZ_VALVE);
//        list.add(model);
//        model = new NodeEquModel();
//        model.setIndex(1);
//        model.setSerial("20100087");
//        model.setPort(2);
//        model.setType(NodeEquModel.NodeEquType.LZ_VALVE);
//        list.add(model);
//        model = new NodeEquModel();
//        model.setIndex(1);
//        model.setSerial("20100088");
//        model.setPort(2);
//        model.setType(NodeEquModel.NodeEquType.LZ_VALVE);
//        list.add(model);
//        model = new NodeEquModel();
//        model.setIndex(1);
//        model.setSerial("20100089");
//        model.setPort(2);
//        model.setType(NodeEquModel.NodeEquType.LZ_VALVE);
//        list.add(model);
//        rnDriver.init(list);
//        NetEqu.setInstance("800001", rnDriver);
        ConcentratorServer.startServer(7002, "LKB_DTU", true);
        LangKaBoDriver driver = new LangKaBoDriver("", "00000013190003", "Lcm200-d", 5000);
        while (true) ;
    }

}
